// 蜂窝蜜造平台生成代码，如手工更改，请添加到 .beeignore 忽略生成

package com.fowo.api.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.common.model.ImportRow;
import com.fowo.api.common.model.RException;
import com.fowo.api.common.util.ResponseUtils;
import com.fowo.api.common.util.SheetUtils;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.mapper.BosAssistantdataDetailMapper;
import com.fowo.api.mapper.ShopInfoMapper;
import com.fowo.api.model.bos.assistantdata.detail.BosAssistantdataDetailItemVo;
import com.fowo.api.model.bos.assistantdata.detail.BosAssistantdataDetailSearchParamPo;
import com.fowo.api.model.shop.info.ShopInfoExcelPo;
import com.fowo.api.model.shop.info.ShopInfoImportPo;
import com.fowo.api.model.shop.info.ShopInfoItemVo;
import com.fowo.api.model.shop.info.ShopInfoSearchParamPo;
import com.fowo.api.model.shop.info.ShopInfoVo;
import com.fowo.api.service.ShopInfoService;
import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.sys.service.FileService;
import com.fowo.api.user.model.JwtUserInfo;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 店铺 服务实现类
 */
@Service
@Slf4j
@DS("ds24")
public class ShopInfoServiceImpl
        extends ShopInfoBaseServiceImpl {

    /** 引用字段排序字段名转换信息 */
    public static final Map<String, String> SORT_FIELD_MAP = new HashMap<>() {
        {
            put("jindieShopDataValue", "bad.`data_value`");
        }
    };
    // 导出时单次查询最大记录数
    protected static final int EXPORT_QUERY_MAX_SIZE = 1000;
    // 支持导出的最大记录数(1048576 为 Excel 支持的最大行数)
    protected static final long EXPORT_MAX_SIZE = 1048575;

    @Resource
    protected BosAssistantdataDetailMapper bosAssistantdataDetailMapper;

    @Resource
    protected FileService fileService;

    @Resource
    protected Validator validator;

    /**
     * 创建店铺
     * @param model 店铺
     * @return 新数据的主键
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(ShopInfoVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        ShopInfo entity = new ShopInfo();
        BeanUtils.copyProperties(model, entity);
        entity.setCreateTime(new Date());
        entity.setLastUpdateTime(new Date());
        if (currentUser != null) {
            entity.setCreateUser(currentUser.getUserId());
            entity.setLastUpdateUser(currentUser.getUserId());
        }
        if (model.getPlatform() == null) {
            entity.setPlatform("Custom");
        }

        if (model.getHasAdsSetting() == null) {
            entity.setHasAdsSetting(false);
        }
        if(entity.getPlatform().equals("Walmart")){
            entity.setSellerAuthStatus("SQ01");
            entity.setAuthTime(new Date());
            entity.setMid(177L);
        }
        if (this.save(entity)) {
            return entity.getId();
        }
        throw new Exception("店铺保存失败");
    }

    /**
     * 更新店铺
     * @param model 店铺
     * @return 更新是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(ShopInfoVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        ShopInfo entity = this.getById(model.getId());
        if (entity == null) {
            throw new Exception("店铺不存在");
        }
        BeanUtils.copyProperties(
                model,
                entity,
                "id",
                "shopName",
                "shopCode",
                "createTime",
                "createUser",
                "lastUpdateTime",
                "lastUpdateUser",
                "country",
                "sellerId",
                "jindieShopCode"
        );
        entity.setLastUpdateTime(new Date());
        entity.setJindieShopCode(model.getJindieShopCode());
        if (currentUser != null) {
            entity.setLastUpdateUser(currentUser.getUserId());
        }
        return this.updateById(entity);
    }

    /**
     * 更新店铺（带空值）
     * @param model 店铺
     * @return 更新是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateForEdit(ShopInfoVo model) throws Exception {
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        ShopInfo entity = this.getById(model.getId());
        if (entity == null) {
            throw new Exception("店铺不存在");
        }
        model.setLastUpdateTime(new Date());
        if (currentUser != null) {
            model.setLastUpdateUser(currentUser.getUserId());
        }
        boolean isOk = new LambdaUpdateChainWrapper<>(baseMapper)
                .set(ShopInfo::getLastUpdateTime, model.getLastUpdateTime())
                .set(ShopInfo::getLastUpdateUser, model.getLastUpdateUser())
                .set(ShopInfo::getJindieShop, model.getJindieShop())
                .eq(ShopInfo::getId, model.getId())
                .update();
        return isOk;
    }

    /**
     * 删除店铺
     * @param id 店铺的主键
     * @return 删除是否成功
     */
    @Override
    public boolean delete(Long id) throws Exception {
        return this.removeById(id);
    }

    /**
     * 批量删除店铺
     * @param ids 店铺的主键列表
     * @return 删除是否成功
     */
    @Override
    public boolean batchDelete(List<Long> ids) throws Exception {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 导入单行处理
     * @param row 要导入的行
     * @param rowNumber 所在行号
     * @param vo 输出VO,可空
     * @param variables 变量池，用于在一次导入过程中保存临时信息
     * @return 导入行对象
     */
    protected ImportRow<ShopInfoImportPo> excelToImportRow(
            ShopInfoImportPo row,
            Integer rowNumber,
            ShopInfoVo vo,
            Map<String, Object> variables
    ) {
        ImportRow<ShopInfoImportPo> ir = new ImportRow<ShopInfoImportPo>();
        ir.setRowNumber(rowNumber);
        ir.setRow(row);
        if (SheetUtils.isAllFieldsEmpty(row)) {
            ir.setEmptyRow(true);
            ir.addError("", "空行");
            return ir;
        }
        final Set<ConstraintViolation<ShopInfoImportPo>> validate = validator.validate(
                row
        );
        boolean isOutputVo = vo != null;
        if (!isOutputVo) {
            vo = new ShopInfoVo();
        }
        BeanUtils.copyProperties(row, vo);
        // 收集基本校验错误
        ir.initErrors(validate, ShopInfoImportPo.class);

        // 一般数据处理
        // 处理关关联字段“金蝶店铺”
        if (!SheetUtils.isBlank(row.getJindieShopDataValue())) {
            BosAssistantdataDetailSearchParamPo jindieShopSearchParam = new BosAssistantdataDetailSearchParamPo();
            jindieShopSearchParam.setLimit(2); // 最大只返回二行记录
            jindieShopSearchParam.setDataValueEq(
                    SheetUtils.trim(row.getJindieShopDataValue())
            );
            List<BosAssistantdataDetailItemVo> jindieShopMatches = bosAssistantdataDetailMapper.search(
                    jindieShopSearchParam
            );
            if (jindieShopMatches.size() == 0) {
                ir.addError(
                        "jindieShopDataValue",
                        "未能在金蝶辅助资料中找到匹配的数据"
                );
            } else if (jindieShopMatches.size() > 1) {
                ir.addError(
                        "jindieShopDataValue",
                        "关联不唯一，在金蝶辅助资料中找到多个匹配的数据"
                );
            } else {
                vo.setJindieShop(jindieShopMatches.get(0).getId());
            }
        }

        return ir;
    }


    /**
     * 导出
     * @param search 查询条件
     */
    @Override
    public void export(
            Long templateId,
            ShopInfoSearchParamPo search,
            HttpServletResponse response
    ) throws Exception {
        search.setPageSize(EXPORT_QUERY_MAX_SIZE);
        int current = 1;
        List<ShopInfoExcelPo> items = new ArrayList<ShopInfoExcelPo>();
        while (true) {
            search.setCurrent(current);
            Page<ShopInfoItemVo> page = this.pageSearch(search);
            if (page.getTotal() > EXPORT_MAX_SIZE) {
                throw new RException("导出记录数超出限制！");
            }
            List<ShopInfoItemVo> list = page.getRecords();
            if (list.isEmpty()) {
                break;
            }
            for (ShopInfoItemVo item : list) {
                ShopInfoExcelPo excel = new ShopInfoExcelPo();
                BeanUtils.copyProperties(item, excel);

                items.add(excel);
            }
            if (list.size() < EXPORT_QUERY_MAX_SIZE) {
                break;
            }
            current++;
        }

        ResponseUtils.setAttachmentFileName(response, "店铺.xlsx");
        EasyExcel
                .write(response.getOutputStream())
                .sheet()
                .head(ShopInfoExcelPo.class)
                .doWrite(items);
    }

    /**
     * 通过名称查询店铺主键(重复时返回最新的主键)
     */
    @Override
    public Long getIdByShopName(String shopName) {
        return this.baseMapper.getIdByShopName(shopName);
    }

    /**
     * 通过名称查询店铺多主键(重复时返回最新的主键)
     */
    @Override
    public List<Long> getIdsByShopName(List<String> list) {
        return this.baseMapper.getIdsByShopName(list);
    }

    /**
     * 通过店铺主键查询名称
     */
    @Override
    public String getShopNameById(Long id) {
        return this.baseMapper.getShopNameById(id);
    }

//    /**
//     * 通过店铺主键查询名称列表
//     */
//    @Override
//    public List<String> getShopNameByIds(List<Long> ids) {
//        return this.baseMapper.getShopNameByIds(ids);
//    }

    /**
     * 获取详情
     * @param id 店铺的主键
     */
    @Override
    public ShopInfoVo getVoById(Long id) throws Exception {
        ShopInfoVo vo = this.baseMapper.selectVoById(id);
        if (vo == null) {
            return null;
        }
        return vo;
    }

    /**
     * 分页查询店铺
     * @param search 查询条件
     * @return 店铺分页查询结果
     */
    @Override
    public Page<ShopInfoItemVo> pageSearch(ShopInfoSearchParamPo search) {
        search.initSort("t.id desc", "t.", SORT_FIELD_MAP);
        Page<ShopInfoItemVo> page =
                this.baseMapper.pageSearch(search.toPage(), search);
        return page;
    }

    /**
     * 列表查询店铺
     * @param search 查询条件
     * @return 店铺列表查询结果
     */
    @Override
    public List<ShopInfoItemVo> search(ShopInfoSearchParamPo search) {
        search.initSort("t.id desc", "t.", SORT_FIELD_MAP);
        return this.baseMapper.search(search);
    }

    /**
     * 查询店铺最后更新时间
     * @param search 查询条件
     * @return 店铺最后更新时间
     */
    @Override
    public Date searchLastUpdateTime(ShopInfoSearchParamPo search) {
        return this.baseMapper.searchLastUpdateTime(search);
    }
}
